// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-11-11

#include "stdafx.h"
#include "svr_asyncqueue.h"
#include "svr_asyncexec.h"

namespace JoyServer
{

CJoyAsyncQueue::CJoyAsyncQueue()
{
    m_exec      = NULL;
    m_finish    = true;
}

CJoyAsyncQueue::~CJoyAsyncQueue()
{
}

bool CJoyAsyncQueue::Create(CJoyAsyncExec* pExec)
{
    ASSERT(m_exec == NULL);

    m_exec      = pExec;
    m_finish    = true;

    return true;
}

void CJoyAsyncQueue::Destroy()
{
    while(!IsEmpty())
    {
        Sleep(100);
    }
}

CJoyAsyncObject* CJoyAsyncQueue::PeekObject()
{
    CJoyAutoCS gate(m_lock);
    if(m_objects.IsEmpty())
    {
        m_finish = true;
        return NULL;
    }
    return m_objects.RemoveHead();
}

void CJoyAsyncQueue::OnExecute()
{
    CJoyAsyncObject* pObj = PeekObject();
    while(pObj != NULL)
    {
        pObj->Execute();
        pObj->Release();
        pObj = PeekObject();
    }
}

void CJoyAsyncQueue::ClearObjects()
{
    CJoyAutoCS gate(m_lock);
    POSITION pos = m_objects.GetHeadPosition();
    while(pos != NULL)
    {
        CJoyAsyncObject* obj = m_objects.GetNext(pos);
        obj->Release();
    }
    m_objects.RemoveAll();
}

bool CJoyAsyncQueue::QueueObject(CJoyAsyncObject* asyObj)
{
    ASSERT(m_exec != NULL);

    CJoyAutoCS gate(m_lock);
    if(m_finish)
    {
        AddRef();
        if(!m_exec->QueueObject(this))
        {
            return false;
        }
        m_finish = false;
    }
    m_objects.AddTail(asyObj);
    return true;
}


} // namespace JoyServer
